#include "BlackDeath.Core.h"

namespace BlackDeath
{
	namespace Core
	{
		#pragma region Constructor and Destructor
		CGame::CGame()
		{
			this->m_pTimer = new BlackDeath::Core::CGameTime();
			this->m_pGameWindow = new BlackDeath::Core::CGameWindow();
			this->m_pGraphicsDevice = new BlackDeath::Graphics::CGraphicsDevice(this->m_pGameWindow);
			
			this->m_pComponentManager = new BlackDeath::Core::CGameComponentManager(this);
			/*TODO:
			this->m_pServicesManager = new BlackDeath::Core::CServiceManager(this);
			this->m_pContentManager = new BlackDeath::Content::CContentManager(this);
			*/
			DWORD processId = ::GetCurrentProcessId();
			HANDLE hProcess = ::OpenProcess(PROCESS_DUP_HANDLE, true, processId);
			::SetPriorityClass(hProcess, ABOVE_NORMAL_PRIORITY_CLASS);//sets the proprity of the thread to above the normal
		}

		CGame::~CGame()
		{
			if(this->m_pComponentManager != NULL)
				delete this->m_pComponentManager;

			/*TODO:
			if(this->m_pServicesManager != NULL)
				delete this->m_pServicesManager;
			*/

			if(this->m_pGameWindow != NULL)
				delete this->m_pGameWindow;

			if(this->m_pGraphicsDevice != NULL)
				delete this->m_pGraphicsDevice;

			/*TODO:
			if(this->m_pContentManager != NULL)
				delete this->m_pContentManager;
			*/
		}
		#pragma endregion

		#pragma region Methods
		void CGame::Initialize()
		{
		}

		void CGame::LoadContent()
		{
		}

		bool CGame::BeginDraw()
		{
			return true;
		}

		void CGame::Draw(BlackDeath::Core::CGameTime* gameTime)
		{			
			this->m_pComponentManager->Draw(this->m_pTimer);			
		}

		void CGame::EndDraw()
		{
			this->m_pGraphicsDevice->Present();
		}

		void CGame::Update(BlackDeath::Core::CGameTime* gameTime)
		{
			this->m_pComponentManager->Update(gameTime);
		}

		void CGame::BeginRun()
		{
			/*TODO:
			this->m_pServicesManager->Initialize();
			*/
			this->m_pGameWindow->Show();
			this->m_pGraphicsDevice->Create();
			this->Initialize();
			this->m_pComponentManager->Initialize();
			this->LoadContent();
			this->m_pComponentManager->LoadContent();			
		}

		void CGame::EndRun()
		{
			this->m_pGraphicsDevice->Destroy();
			this->m_pGameWindow->Close();
			
			
			delete this->m_pComponentManager;
			/*TODO:
			delete this->m_pServicesManager;
			delete this->m_pContentManager;
			*/
		}
		#pragma endregion

		#pragma region Options
		void CGame::Run()
		{
			MSG msg = {0};
			this->BeginRun();

			this->m_pTimer->Reset();
			while(msg.message != WM_QUIT)
			{
				if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
				{
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
				else
				{
					this->m_pTimer->Tick();
					this->Update(this->m_pTimer);
					if(this->BeginDraw())
					{
						this->Draw(this->m_pTimer);
						this->EndDraw();
					}

					::ValidateRect(this->m_pGameWindow->Get_Handle(), NULL);
				}
			}

			this->EndRun();
		}
		
		void CGame::Exit()
		{
			::PostMessage(this->m_pGameWindow->m_hWnd, WM_QUIT, 0, 0); 
		}
		#pragma endregion

		#pragma region Properties
		BlackDeath::Graphics::CGraphicsDevice* CGame::Get_GraphicsDevice()
		{
			return this->m_pGraphicsDevice;
		}

		BlackDeath::Core::CGameWindow* CGame::Get_Window()
		{
			return this->m_pGameWindow;
		}
		#pragma endregion
	}
}